package server;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Scanner;
import java.rmi.AccessException;
import java.rmi.Naming;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class BillingServer extends java.rmi.server.UnicastRemoteObject implements BillingServerInterface {

	private Registry registry;
	private int port;
	private String host;
	private String billingName;
	private BillingServerSecure billingServerSecure;

	private BillingServer(String[] args) throws RemoteException {
		if(args.length!=1) usage();
		billingName=args[0];
		billingServerSecure = new BillingServerSecure();
		try {
			Properties props = new Properties();
			java.io.InputStream is = ClassLoader.getSystemResourceAsStream("./registry.properties");
			props.load(is);

			if (is != null) {
				try {			
					

					port = Integer.parseInt(props.getProperty("registry.port"));
					host = props.getProperty("registry.host");
					
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} finally {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			} else {
				System.err.println("Properties file not found!");
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		//port = 12119;
		
		try {
			registry = LocateRegistry.getRegistry(host,port);
			registry.rebind(billingName, this);
		} catch (RemoteException e) {
			registry = LocateRegistry.createRegistry(port);
			registry.rebind(billingName, this);
		}
		
		run();
	}
	
	private void run() throws RemoteException {
		Scanner stdin =  new Scanner(System.in);
		String userinput;
		boolean isActive = true;
		while (isActive) {
			userinput=stdin.nextLine().trim();
			if(userinput.equals("!exit")) {
				shutDown();
				isActive = false;
			}

		}
		stdin.close();
	}

	private void shutDown() throws RemoteException {
		try {
			registry.unbind(billingName);
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		UnicastRemoteObject.unexportObject(this, true);
		System.exit(0);
	}

	private void usage() {
		System.out.println("Usage: java BillingServer <billing server binding name>\nExample: java BillingServer billingServer");
		System.exit(0);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			//instantiate rmiServer
			BillingServer bserver = new BillingServer(args);



		} catch (Exception e) {
			System.err.println("RMI server exception: " + e);
			e.printStackTrace();
		}

	}	

	@Override
	public BillAuctionInterface login(String username, String password){

		try {
			Properties props = new Properties();
			java.io.InputStream is = ClassLoader.getSystemResourceAsStream("./user.properties");
			props.load(is);

			if (is != null) {
				try {			
					String md5Pw = md5(password);

//					System.out.println("umgewandeltes pw: "+md5Pw);

					String user = props.getProperty(username);
//					System.out.println("propertie vom username: "+user);

					if(md5Pw.equals(user)){
						return (BillAuctionInterface)billingServerSecure;
					}
					
				} finally {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			} else {
				System.err.println("Properties file not found!");
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}


		return null;
	}

	public static String md5(String input){
		String res = "";
		try {
			MessageDigest algorithm = MessageDigest.getInstance("MD5");
			algorithm.reset();
			algorithm.update(input.getBytes());
			byte[] md5 = algorithm.digest();
			String tmp = "";
			for (int i = 0; i < md5.length; i++) {
				tmp = (Integer.toHexString(0xFF & md5[i]));
				if (tmp.length() == 1) {
					res += "0" + tmp;
				} else {
					res += tmp;
				}
			}
		} catch (NoSuchAlgorithmException ex) {}
		return res;
	}

}
